package com.reading.cms.controller.system;

import com.google.code.kaptcha.Constants;
import com.reading.cms.controller.BaseController;
import com.reading.cms.utils.ServletUtil;
import com.reading.cms.utils.ShiroUtil;
import com.reading.common.cache.constant.SmsCodeType;
import com.reading.common.entity.system.SysUser;
import com.reading.common.utils.StringUtil;
import com.reading.core.manager.system.ISystemUserManager;
import com.reading.common.utils.JsonResult;
import com.reading.message.service.SmsService;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 登录验证
 *
 * @author ruoyi
 */
@Slf4j
@Controller
public class LoginController extends BaseController {

    // 验证码开关
    @Value("${shiro.user.captchaEbabled}")
    private boolean captchaEbabled;

    // 验证码类型
    @Value("${shiro.user.captchaType}")
    private String captchaType;

    // 短信验证码开关
    @Value("${shiro.user.smsCaptchaEbabled}")
    private boolean smsCaptchaEbabled;

    @Resource
    private SmsService smsService;

    @Resource
    private ISystemUserManager userManager;

    @GetMapping("/login")
    public String login(HttpServletRequest request, HttpServletResponse response, Model model) {
        // 如果是Ajax请求，返回Json字符串。
        if (ServletUtil.isAjaxRequest(request)) {
            return ServletUtil.renderString(response, "{\"code\":\"1\",\"msg\":\"未登录或登录超时。请重新登录\"}");
        }
        model.addAttribute("captchaEbabled",captchaEbabled);
        model.addAttribute("captchaType",captchaType);
        model.addAttribute("smsCaptchaEbabled",smsCaptchaEbabled);
        return "login";
    }

    @PostMapping("/login")
    @ResponseBody
    public JsonResult ajaxLogin(String username, String password, Boolean rememberMe) {
        UsernamePasswordToken token = new UsernamePasswordToken(username, password, rememberMe);
        Subject subject = SecurityUtils.getSubject();
        try {
            subject.login(token);
            return success();
        } catch (AuthenticationException e) {
            String msg = "用户或密码错误";
            return error(msg);
        }
    }

    @PostMapping("/sms")
    @ResponseBody
    public JsonResult sendSmsCode() {
        try {
            Session session = ShiroUtil.getSession();
            String username = ServletUtil.getParameter("username");
            String password = ServletUtil.getParameter("password");
            if (StringUtil.isEmpty(username) || StringUtil.isEmpty(password)) {
                return error("请输入用户名/密码");
            }
            //判断session中是否已存在验证码
            String context = (String) session.getAttribute(Constants.KAPTCHA_SESSION_KEY);
            if (!StringUtil.isEmpty(context)) {
                String[] code = context.split(",");
                long lastSendTime = Long.parseLong(code[1]);
                if ((System.currentTimeMillis() - lastSendTime) < 60000) {
                    return error("请勿重复发送验证码");
                }
            }
            SysUser sysUser = userManager.selectUserByLoginName(username);
            if (sysUser == null || StringUtil.isEmpty(sysUser.getMobileNo())) {
                return error("发送短信验证码失败，请联系平台");
            }
            //生成短信验证码
            String smsCode = StringUtil.genRandomNum(6);
            int status = smsService.sendSmsCode(SmsCodeType.CMSLOGIN.getTypeCode(), sysUser.getMobileNo(), smsCode);
            if (status == 0) {
                session.setAttribute(Constants.KAPTCHA_SESSION_KEY, smsCode + "," + System.currentTimeMillis());
                return success();
            } else {
                return error("发送短信验证码失败");
            }
        } catch (Exception e) {
            log.error("发送短信验证码失败", e);
            return error("发送短信验证码失败");
        }
    }


    @GetMapping("/unauth")
    public String unauth() {
        return "/error/unauth";
    }
}
